package logbook.gui;

import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

import logbook.gui.logic.TableItemCreator;
import logbook.utils.JsonUtils;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.KeyListener;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.Text;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

public class ApplicationMain {
    private static final Path DATA_PATH = Paths.get("data/start2.json");

    private static final List<String[]> FULL_BODY = new ArrayList<String[]>(500);

    protected Shell shell;

    private Text text;

    private Table table;

    /** メニューバー */
    protected Menu menubar;

    /** [操作]メニュー */
    protected Menu opemenu;

    /** テーブルに表示しているボディー */
    protected List<String[]> body = new ArrayList<String[]>(500);

    private TableColumn id_col;

    private TableColumn name_col;

    private TableColumn file_name_col;

    /**
     * Launch the application.
     * 
     * @param args
     */
    public static void main(String[] args) {
        try {
            ApplicationMain window = new ApplicationMain();
            window.open();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * Open the window.
     */
    public void open() {
        Display display = Display.getDefault();
        createContents();

        loadBodyData();

        body.addAll(FULL_BODY);

        setTableBody();
        packTableHeader();

        shell.open();
        shell.layout();
        while (!shell.isDisposed()) {
            if (!display.readAndDispatch()) {
                display.sleep();
            }
        }
    }

    /**
     * Create contents of the window.
     */
    protected void createContents() {
        shell = new Shell();
        shell.setSize(340, 600);
        shell.setText("天津风我喜欢你啊~");
        shell.setLayout(new GridLayout(2, false));

        text = new Text(shell, SWT.BORDER);
        text.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
        text.addKeyListener(new KeyListener() {

            @Override
            public void keyReleased(org.eclipse.swt.events.KeyEvent event) {
                if (event.keyCode != 13) {
                    doSearch();
                }
            }

            @Override
            public void keyPressed(org.eclipse.swt.events.KeyEvent event) {
                if (event.keyCode == 13) {
                    doSearch();
                }
            }

            private void doSearch() {
                String search_name = text.getText().trim();
                body = "".equals(search_name) ? FULL_BODY : FULL_BODY.stream().filter(line -> line[1].contains(search_name) || line[2].contains(search_name)).collect(Collectors.toList());
                reloadTable();
            }
        });

        table = new Table(shell, SWT.BORDER | SWT.FULL_SELECTION);
        table.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 2, 1));
        table.setHeaderVisible(true);
        table.setLinesVisible(true);

        this.menubar = new Menu(this.shell, SWT.BAR);
        this.shell.setMenuBar(this.menubar);

        MenuItem operoot = new MenuItem(this.menubar, SWT.CASCADE);
        operoot.setText("操作");
        this.opemenu = new Menu(operoot);
        operoot.setMenu(this.opemenu);

        id_col = new TableColumn(table, SWT.NONE);
        id_col.setWidth(50);
        id_col.setText("ID");

        name_col = new TableColumn(table, SWT.NONE);
        name_col.setText("Name");

        file_name_col = new TableColumn(table, SWT.NONE);
        file_name_col.setWidth(200);
        file_name_col.setText("File_Name");
    }

    /**
     * テーブルボディーをセットする
     */
    protected void setTableBody() {
        TableItemCreator creator = TableItemCreator.DEFAULT_TABLE_ITEM_CREATOR;
        creator.init();

        for (int i = 0; i < this.body.size(); i++) {
            String[] line = this.body.get(i);
            creator.create(this.table, line, i);
        }
    }

    private void loadBodyData() {
        FULL_BODY.clear();

        try {
            JSONObject api_data = JsonUtils.readJsonObjectFromFile(DATA_PATH).getJSONObject("api_data");
            JSONArray api_mst_ship = api_data.getJSONArray("api_mst_ship");
            JSONArray api_mst_shipgraph = api_data.getJSONArray("api_mst_shipgraph");

            for (int i = 0; i < api_mst_ship.size(); i++) {
                JSONObject ship = api_mst_ship.getJSONObject(i);
                String id = ship.getString("api_id");
                String name = ship.getString("api_name");
                String file_name = api_mst_shipgraph.getJSONObject(i).getString("api_filename");
                FULL_BODY.add(new String[] { id, name, file_name });
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * テーブルをリロードする
     */
    protected void reloadTable() {
        this.shell.setRedraw(false);
        int topindex = this.table.getTopIndex();
        int selection = this.table.getSelectionIndex();

        this.table.setSortColumn(null);

        this.disposeTableBody();
        this.setTableBody();
        this.packTableHeader();

        this.table.setSelection(selection);
        this.table.setTopIndex(topindex);
        this.shell.setRedraw(true);
    }

    /**
     * テーブルヘッダーの幅を調節する
     */
    protected void packTableHeader() {
        for (TableColumn column : table.getColumns()) {
            column.pack();
        }
    }

    /**
     * テーブルボディーをクリアする
     */
    protected void disposeTableBody() {
        for (TableItem item : this.table.getItems()) {
            item.dispose();
        }
    }
}
